﻿using System;
using System.Collections.Generic;
using System.Linq;
using Epam.Exceptions.BusinessLogicExceptions;
using Epam.Exceptions.RepositoryExceptions;
using Epam.PeopleInterfaces;
using Epam.PeopleModel;


namespace Epam.BusinessLogic
{
    public class PeopleService:IPeopleService
    {
        private readonly IPeopleRepository _repository;

        private readonly IFilterAlgoritm _filterAlgoritm;

        public PeopleService(IPeopleRepository repository,IFilterAlgoritm filterAlgoritm)
        {
            _repository = repository;
            _filterAlgoritm = filterAlgoritm;
        }

        public void Create(IPeopleEntity entity)
        {
            try
            {
                _repository.Create(entity);
            }
            catch (CrudOperationException e)
            {
                throw new DatabaseException(e.Message);
            }
            
        }

        public void Update(IPeopleEntity entity)
        {
            try
            {
                _repository.Update(entity);
            }
            catch (CrudOperationException e)
            {
                throw new DatabaseException(e.Message);
            }
            
        }

        public void Delete(Guid id)
        {
            try
            {
                _repository.Delete(id);
            }
            catch (CrudOperationException e)
            {
                throw new DatabaseException(e.Message);
            }
            
        }

        public IPeopleEntity GetById(Guid id)
        {
            try
            {
                return PeopleMapper.Convert(_repository.GetById(id));
            }
            catch (FindOperationException e)
            {
                throw new DatabaseException(e.Message);
            }
            
        }

        public IViewPeopleEntity GetViewEntityById(Guid id)
        {
            try
            {
                return PeopleMapper.ConvertDtoToView(_repository.GetById(id), _filterAlgoritm);
            }
            catch (FindOperationException e)
            {
                throw new DatabaseException(e.Message);
            }
        }

        public ICollection<IViewPeopleEntity> GetViewEntityByPage(int currentPage, int itemPerPage)
        {
            try
            {
                return (from obj in _repository.ReadPage(currentPage, itemPerPage)
                        select PeopleMapper.ConvertDtoToView(obj, _filterAlgoritm)).ToList();
            }
            catch (FindOperationException e)
            {
                throw new DatabaseException(e.Message);
            }
           

        }

        public ICollection<IViewPeopleEntity> GetAllViewEntity()
        {
            try
            {
                return (from obj in _repository.ReadAll()
                        select PeopleMapper.ConvertDtoToView(obj, _filterAlgoritm)).ToList();
            }
            catch (FindOperationException e)
            {
                throw new DatabaseException(e.Message);
            }
           
        }

        public ICollection<IPeopleEntity> GetAll()
        {
            try
            {
                return (from obj in _repository.ReadAll()
                        select PeopleMapper.Convert(obj)).ToList();
            }
            catch (FindOperationException e)
            {
                throw new DatabaseException(e.Message);
            }
            
        }

        public ICollection<IPeopleEntity> GetByPage(int currentPage, int itemPerPage)
        {
            try
            {
                return (from obj in _repository.ReadPage(currentPage, itemPerPage)
                        select PeopleMapper.Convert(obj)).ToList();
            }
            catch (Exception e)
            {
                throw new DatabaseException(e.Message);
            }
            
        }

        public ICollection<IViewPeopleEntity> Filter(double lowfactor,double hightfactor,IFilterAlgoritm filterAlgoritm)
        {
            try
            {
                return (from obj in _repository.Filter(lowfactor, hightfactor, filterAlgoritm)
                        select PeopleMapper.ConvertDtoToView(obj, _filterAlgoritm)).ToList();
            }
            catch(FindOperationException e)
            {
                throw new DatabaseException(e.Message);
            }

        }

        public IPeopleEntity NewEntity(string name, DateTime birthdate, double weight, double height)
        {
            return new PeopleEntity(Guid.NewGuid(), name, birthdate, weight, height);
        }
    }
}
